package com.jimet.server;

import java.util.Date;
import javax.crypto.*;
import javax.servlet.http.*;
import com.jimet.security.AES;
import com.jimet.security.HexConverter;


public class JimetSession 
{
	private String tokenKey;
	private SecretKey cryptoKey;
	private String  sessionIDOnCreate;
	private Date creationDate;
	private JimetServerUser jUser;
	

	public JimetSession(){	
	}
	
	
	/** Called by the Jimet Server on authenticated session creation.
	 * @param secretKey
	 * @param juser
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public String initialize(SecretKey secretKey, JimetServerUser juser, HttpServletRequest request) throws Exception
	{
		this.cryptoKey 			= secretKey;
		this.jUser 				= juser;
		this.creationDate 		= new Date();
		HttpSession session 	= request.getSession();
		this.sessionIDOnCreate 	= session.getId();
		byte [] encryptedSessionIDOnCreate = AES.encrypt(sessionIDOnCreate, this.cryptoKey);
		String hexOfEncryptedSessionIDOnCreate = HexConverter.byteArrayToHexString(encryptedSessionIDOnCreate);
		session.setMaxInactiveInterval(JimetConfiguration.getInt("Session.TIMEOUT_INTERVAL_SECONDS"));
		this.tokenKey			= hexOfEncryptedSessionIDOnCreate.substring(0,8);;
		return hexOfEncryptedSessionIDOnCreate;
	}

	
	/** Checks whether the session is valid. 
	 * If not valid; redirects to the configured sessiontime out page.
	 * If valid; sets the configured response headers. (e.g: encoding) 
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	public void onAuthenticatedPageStart(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		String token = request.getParameter(JimetConfiguration.getString("Session.TOKEN_NAME")); 
		if( (token==null) || !(this.isValid(token)))
		{
			response.sendRedirect(request.getContextPath()+"/"+JimetConfiguration.getString("Session.TIMEOUT_URL")+"?timeout=true");
		}
	}
	
	/** Method to get the total number of web users browsing the web application.
	 * @return - number of users including authenticated and unauthenticated
	 */
	public int getSessionCount()
	{
		return JimetSessionListener.getSessionCount();
	}

	/** Method to get the total number of authenticated users browsing the web application.
	 * @return - number of current authenticated users 
	 */
	public int getAuthenticatedSessionCount()
	{
		return JimetSessionListener.getAuthenticatedSessionCount();
	}
	
	/**	 encrypt the session id stored on initialization of the session, 
	 * using the session specific Secret Key stored on the user session on the server.
	 *  and then compare with the UR-Rewritten token 
	 * @param hexToken
	 * @return true if the session is valid
	 * 			false if the session is invalid or timed out.
	 * @throws Exception
	 */
	public boolean isValid(String hexToken) throws Exception
	{
		if((this.cryptoKey == null) || (this.jUser == null) || (this.creationDate == null) || (this.sessionIDOnCreate == null) || hexToken == null)
			return false;
		
		byte [] encryptedSessionIDOnCreate = AES.encrypt(sessionIDOnCreate, this.cryptoKey);
		String hexOfEncryptedSessionIDOnCreate = HexConverter.byteArrayToHexString(encryptedSessionIDOnCreate);

		if(hexToken.equalsIgnoreCase(hexOfEncryptedSessionIDOnCreate))
			return true;
		else
			return false;
	}

	
	
	/**
	 * @return Returns the sessionIDOnCreate.
	 */
	public String getSessionIDOnCreate() {
		return sessionIDOnCreate;
	}

	/**
	 * @param sessionIDOnCreate The sessionIDOnCreate to set.
	 */
	public void setSessionIDOnCreate(String sessionIDOnCreate) {
		this.sessionIDOnCreate = sessionIDOnCreate;
	}

	public JimetServerUser getUser()
	{
		return this.jUser;
	}
	
	public String getTokenKey() {
		return tokenKey;
	}

	public void setTokenKey(String tokenKey) {
		this.tokenKey = tokenKey;
	}


	public void invalidate(HttpServletRequest request) throws Exception
	{		
		this.cryptoKey = null;
		this.sessionIDOnCreate = null;
		this.creationDate = null;
		this.jUser = null;
		if ( this.tokenKey != null )
		{
			HttpSession session 	= request.getSession();
			session.removeAttribute(this.tokenKey);
			this.tokenKey = "";
		}
		
		if ( this.jUser != null )
			this.jUser.logAction("LOGOUT");
	}
	
}
